package testes;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import baseClass.*;
import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

/**
 * @author jonhnanthan
 *
 */
public class UserTest {

	private User user1, user2;
	private Map<String, Integer> mapa = new HashMap<String, Integer>();
	
	@Before
	public void User(){
		mapa.put("rest1", 5);
		mapa.put("rest2", 4);
		try {
			user1 = new User("Jonhnanthan", mapa);
		} catch (Exception e) {
			Assert.fail("O usuario nao foi criado corretamente!");
		}

		try {
			user2 = new User(null, mapa);
			Assert.fail("O usuario foi criado incorretamente!");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem errada", "Nome nao pode ser nulo ou vazio!", e.getMessage());
		}
	}
	
	@Test
	public void testGetOpinioes() {
		Assert.assertEquals("Erro nas opinioes", mapa, user1.getOpinioes());
		Assert.assertEquals("user2 deveria nao existir", null, user2);
	}

	@Test
	public void testSetOpinioes() {
		Map<String, Integer> mapaAux = new HashMap<String, Integer>();
		mapaAux.put("testa1", 15);
		mapaAux.put("testa2", 25);
		Assert.assertEquals("Erro nas opinioes", mapa, user1.getOpinioes());
		user1.setOpinioes(mapaAux);
		Assert.assertEquals("Erro ao setar opinioes", mapaAux, user1.getOpinioes());
	}

	@Test
	public void testGetNome() {
		Assert.assertEquals("Erro de nome", "Jonhnanthan", user1.getNome());
		Assert.assertEquals("user2 deveria nao existir", null, user2);
	}

	@Test
	public void testGetSemelhantes() {
		List<User> usuarios = new ArrayList<User>();
		List<User> usuariosAux = new ArrayList<User>();
		Map<String, Integer> mapaAux = new HashMap<String, Integer>();
		User userAux1 = null, userAux2 = null;
		
			try {
				userAux1 = new User("Jonh", mapa);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			mapaAux.put("rest3", 0);
			mapaAux.put("rest4", -1);
			
			try {
				userAux2 = new User("Victor", mapaAux);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		usuarios.add(userAux1);
		usuarios.add(userAux2);
		usuarios.add(user1);
		
		try {
			user1.getSemelhantes(usuariosAux);
			Assert.fail("Esperava excecao de lista de usuarios vazia");
		} catch (Exception e1) {
			Assert.assertEquals("Erro no em getSemelhantes","Lista de usuarios nao pode ser vazia",e1.getMessage());
		}	
		try {
			Assert.assertEquals("Erro no getSemelhantes", "Jonh",user1.getSemelhantes(usuarios).get(0).getNome());
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			Assert.assertEquals("Erro no getSemelhantes", "Victor",user1.getSemelhantes(usuarios).get(1).getNome());
		} catch (Exception e) {
			e.printStackTrace();
		}
			
		
	}
	
	@Test
	public void testGetMelhores(){
		Map<String,Integer> positivas = new HashMap<String, Integer>();
		for (String chave : user1.getOpinioes().keySet()) {
			if (user1.getOpinioes().get(chave) > 0) {
				positivas.put(chave, user1.getOpinioes().get(chave));
			}
		}
		for (List<String> lista : user1.getMelhores().values()) {
			for (String string : lista) {
				Assert.assertTrue("Erro no getMelhores",positivas.keySet().contains(string));
			}
		}
		
		
		
	}
	@Test
	public void testGetOpnioesZeradas(){
		Assert.assertEquals("Erro nas opinioes zeradas", 0, user1.getOpnioesZeradas().size());
		Assert.assertEquals("Erro nas opinioes zeradas", null, user2);
	}
	
	@Test
	public void testGetNumOpinioesPositivas(){
		Assert.assertEquals("Erro na quantidade de opinioes positivas", 2, user1.getNumOpinioesPositivas());
		Assert.assertEquals("Erro na quantidade de opinioes positivas", null, user2);
	}
	
	@Test
	public void testZerarOpiniao(){
		Assert.assertEquals("Erro no zera opinioes", "rest1", user1.ZerarOpiniao());
		Assert.assertEquals("Erro no zera opinioes", "rest2", user1.ZerarOpiniao());
		Assert.assertEquals("Erro no zera opinioes", "Opinioes zeradas", user1.ZerarOpiniao());
		Assert.assertEquals("Erro no zera opinioes", null, user2);
	}
	
	
	@Test
	public void testRecuperarOpinioes(){
		
		Assert.assertEquals("Erro ao zerar opinioes", "rest1", user1.ZerarOpiniao());
		Assert.assertEquals("Erro ao zerar opinioes", "rest2", user1.ZerarOpiniao());
		Assert.assertEquals("Erro ao zerar opinioes", "Opinioes zeradas", user1.ZerarOpiniao());
		
		user1.recuperarOpinioes();
		Assert.assertEquals("Opinioes erradas", mapa, user1.getOpinioes());
		
		Assert.assertEquals("user 2 nao eh nulo", null, user2);
	}
	
	@Test
	public void testEqualsObject() {
		Assert.assertEquals("user2 deveria nao existir", false, user1.equals(user2));
		Assert.assertEquals("user2 deveria nao existir", true, user1.equals(user1));
	}

}
